/*******************************************************************************
 * Creator: Jose Castillo jocasal@gmail.com
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *     * Redistributions of source code must retain the above copyright
 *       notice, this list of conditions and the following disclaimer.
 *     * Redistributions in binary form must reproduce the above copyright
 *       notice, this list of conditions and the following disclaimer in the
 *       documentation and/or other materials provided with the distribution.
 *     * Neither the name of the <organization> nor the
 *       names of its contributors may be used to endorse or promote products
 *       derived from this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED. IN NO EVENT SHALL DANIEL MURPHY BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 ******************************************************************************/
/**
 * Created at 25 Mar, 2011
 */
package packbridge;

/**
 *
 * @author jose
 */
public class Generacion {

    public int poblacion=10;

    public Puente individuos[];


    public Generacion(int p){
        poblacion = p;
        individuos = new Puente[poblacion];

        for(int i=0; i<poblacion; i++){

            individuos[i]= new Puente();

        }
    }

    public void cruzarymutar(){

    int total_fitness = individuos[0].fitness;

    for(int i=1; i<poblacion; i++){

            total_fitness = total_fitness + individuos[i].fitness;
        }


    // algoritmo de ordenacion por insercion adaptado


     for (int i=1; i<individuos.length; i++) {
         Puente aux = individuos[i];
         int j;
         for (j=i-1; j>=0 && individuos[j].fitness<aux.fitness; j--)
            individuos[j+1] = individuos[j];
         individuos[j+1] = aux;
      }

   int buenos=0; //los que van a participar del proceso de cruce
    while(individuos[buenos].fitness>=(total_fitness/poblacion)){
    buenos++;
    }

// fin ordenacion

     System.out.println("Fitness ordenados");
     System.out.println(buenos);
     int k=4;
     Puente individuos_aux[] = new Puente[poblacion];

    for(int i=0; i<poblacion; i++){
        double p_reproduccion = ((double)individuos[i].fitness/(double)total_fitness)*100*(poblacion/2);
        if (i<=1) { // con esto copio igual el primero y el segundo y el tercero y cuarto serán mutaciones de estos dos
            p_reproduccion = 100;
            individuos_aux[i] = individuos[i];
            individuos_aux[i+2]=individuos[i].cruzar(individuos[i]);
        }

        System.out.print("Fitness "+i+": "+individuos[i].fitness+" P.Reproduccion: "+p_reproduccion);
        if((p_reproduccion + Math.random()*100)>100){ // se reproduce con cualquiera de los buenos
        int cualquiera = (int)(Math.random()*buenos); //
        Puente aux = individuos[cualquiera];
        System.out.print(" Cruce con: "+cualquiera+" ");
        Puente hijo = individuos[i].cruzar(aux);

        if(k<poblacion){
        individuos_aux[k] = hijo;
        k++;
        }
        }
        System.out.println("");

    }

     int iaux=0;
       for(;k<poblacion-1;k++){ // si quedan por rellenar, se cruzan otra vez buenos con los primeros
        int cualquiera = (int)(Math.random()*buenos);
        Puente aux = individuos[cualquiera];
        Puente hijo = individuos[iaux].cruzar(aux);
        individuos_aux[k] = hijo;
        iaux++;
        }

     individuos_aux[poblacion-1] = individuos[0].cruzar(new Puente());

     System.arraycopy(individuos_aux, 0, individuos, 0, poblacion);



    // fin de la ordenacion

    }

}
